import { java } from '@codemirror/lang-java';
import CodeMirror, { Compartment, ReactCodeMirrorRef } from '@uiw/react-codemirror/esm';
import { Button, Input, Popover, Tag, Tooltip } from 'antd';
import { FC } from 'react';

import { get } from '@/api';
import { Category } from '@/components/base/Category';
import { useDictStore } from '@/store/dict';

interface ExpressionProps {
  placeholder?: string;
  value?: string;
  onChange?: (value: string) => void;
  className?: string;
}

const javaLang = new Compartment().of(java());

export const Expression: FC<ExpressionProps> = memo((props) => {
  const [code, setCode] = useState<string>(props.value || '');
  const { systemVars } = useDictStore();
  const [execFuncs, setExecFuncs] = useState<string[]>([]);
  const codeMirrorRef = useRef<ReactCodeMirrorRef>();
  const dragData = useRef<string>('');
  const [visible, setVisible] = useState(false);

  const onOpen = () => {
    setVisible(true);
    setTimeout(() => {
      if (codeMirrorRef.current) {
        const editor = codeMirrorRef.current.editor;
        editor?.addEventListener('dragover', (event) => {
          event.preventDefault();
        });

        editor?.addEventListener('drop', (event) => {
          event.preventDefault();
          const view = codeMirrorRef.current?.view;
          if (!view) return;
          const pos = view.posAtCoords({ x: event.clientX, y: event.clientY });
          const transaction = view.state.update({
            changes: { from: pos!, insert: dragData.current }
          });
          view.dispatch(transaction);
        });
      }
    });
  };

  useEffect(() => {
    get('/dict/funcs', {} as never).then((funcs) => {
      setExecFuncs(funcs);
    });
  }, []);

  return (
    <Popover
      title="表达式编辑"
      open={visible}
      destroyTooltipOnHide
      placement="left"
      content={
        <div className="w-650 min-h-190">
          <Category>函数</Category>
          <div className="py-8">
            {execFuncs.map((value) => {
              return (
                <Tooltip title={value}>
                  <Tag
                    draggable
                    onDragStart={() => {
                      dragData.current = value;
                    }}
                    key={value}
                    className="cursor-pointer text-blue-500 mb-4">
                    {value}
                  </Tag>
                </Tooltip>
              );
            })}
          </div>
          <Category>系统变量</Category>
          <div className="py-8">
            {systemVars.map((item) => {
              return (
                <Tooltip title={item.varLabel}>
                  <Tag
                    draggable
                    onDragStart={() => {
                      dragData.current = item.varName!;
                    }}
                    key={item.varName}
                    className="cursor-pointer text-blue-500">
                    {item.varName}
                  </Tag>
                </Tooltip>
              );
            })}
          </div>
          <Category subTitle="可将函数或系统变量拖进编辑器">表达式</Category>
          {/* <div ref={editor} className="w-500 h-170 border border-gray-200 border-solid"></div> */}
          <CodeMirror
            value={code}
            onChange={(value) => {
              setCode(value);
            }}
            extensions={[javaLang]}
            ref={codeMirrorRef as any}
            width="650px"
            height="170px"
            className="border border-gray-200 border-solid mt-4"
          />
          <div className="py-12 flex gap-12 justify-end">
            <Button
              onClick={() => {
                setVisible(false);
              }}
              size="middle"
              type="text">
              取消
            </Button>
            <Button
              onClick={() => {
                props.onChange?.(code);
                setVisible(false);
              }}
              size="middle"
              type="primary">
              确定
            </Button>
          </div>
        </div>
      }>
      <Input className={props.className} onClick={onOpen} placeholder={props.placeholder} value={props.value} readOnly />
    </Popover>
  );
});
